﻿using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using SiemensOPC;
using System.Runtime.CompilerServices;
using VswService_V7.Config;
using VswService_V7.DataBase.Tables;
using System.Data;
using System.Threading;
using VswService_V7.Utility;
using VswService_V7.DataBase.Tables.L2INTERFACE;
/// <summary>
/// Entry Plc StripLoad Command , StripLoadAddress, StripLoadAddress rsp
/// </summary>
namespace VswService_V7.OPC.DB
{
    public class StripLoadAddressDbData : SubscriptionDbDataBase
    {
        public StripLoadAddressDbData(SimaticOPCClient opc, NodeConfig nodes) : base(opc, nodes)
        {
            _askStripsNoList = new string[11] { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" };
            _availableAskStripsNoList = new List<string>();
            askAvailableStripsNoList = new List<string>();
            UnAvailableStripNum = new List<int>();
        }

        /// <summary>
        /// 扫码的请求列表
        /// </summary>
        string[] _askStripsNoList;

        /// <summary>
        /// 非0 有效的stripNo 集合
        /// </summary>
        List<string> _availableAskStripsNoList;

        List<string> askAvailableStripsNoList;//合法的stripNo集合
        List<int> UnAvailableStripNum;//不合法的stripNo序号
                                      //bool isGetAvailableAskStripsNoList = true;//是否不停的去获取有效的stripNo

        public override void CreateSubscription()
        {
            try
            {
                opcServer.QuickAddMonitorItem(opcNodes.StripLoadAddress.GrpoupName,
                    opcNodes.StripLoadAddress.PublishTime,
                    opcNodes.StripLoadAddress.SampleTime,
                    opcNodes.StripLoadAddress.GetNodeAddress(),
                    opcNodes.StripLoadAddress.GetNodeDisplayName(),
                    SubscriptionHandler_StripLoadAddress);

                opcServer.QuickAddMonitorItem(opcNodes.StripLoadAskListAddress.GrpoupName,
                    opcNodes.StripLoadAskListAddress.PublishTime,
                    opcNodes.StripLoadAskListAddress.SampleTime,
                    opcNodes.StripLoadAskListAddress.GetNodeAddress(),
                    opcNodes.StripLoadAskListAddress.GetNodeDisplayName(),
                    SubscriptionHandler_StripLoadAskListAddress);

                opcServer.QuickAddMonitorItem(opcNodes.StripLoadRspListAddress.GrpoupName,
                    opcNodes.StripLoadRspListAddress.PublishTime,
                    opcNodes.StripLoadRspListAddress.SampleTime,
                    opcNodes.StripLoadRspListAddress.GetNodeAddress(),
                    opcNodes.StripLoadRspListAddress.GetNodeDisplayName(),
                    SubscriptionHandler_StripLoadRspListAddress);

                opcServer.QuickAddMonitorItem(opcNodes.StripInUncoilerAddress.GrpoupName,
                    opcNodes.StripInUncoilerAddress.PublishTime,
                    opcNodes.StripInUncoilerAddress.SampleTime,
                    opcNodes.StripInUncoilerAddress.GetNodeAddress(),
                    opcNodes.StripInUncoilerAddress.GetNodeDisplayName(),
                    SubscriptionHandler_StripLoadInUncoiler);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("StripLoad CreateSubscription", ex);
                throw ex;
            }
        }


        bool stripLoadAskResult = false;
        int requestId = 0;
        /// <summary>
        /// 接收STRIP 查询 和 上卷 请求
        /// </summary>
        /// <param name="monitoredItem"></param>
        /// <param name="e"></param>
        private void SubscriptionHandler_StripLoadAddress(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
            if (notification == null || notification.Value.Value == null)
                return;
            if (monitoredItem.DisplayName == "StripLoadAsk")
            {
                stripLoadAskResult = false;
                if (bool.TryParse(notification.Value.Value.ToString(), out stripLoadAskResult))
                {
                    if (stripLoadAskResult)
                    {
                        requestId += 1;
                        Task.Run(()=>RequestStripInfo());
                        //获取非0的有效的stripNo : availableAskStripsNoList
                        //GetAvailableAskStripsNoList();
                        //try
                        //{
                        //    //2. 获取数据库表中可以上料的Strip
                        //    if (!_availableAskStripsNoList.Equals(null) && _availableAskStripsNoList.Count > 0)
                        //    {
                        //        //查出 _availableAskStripsNoList 里状态是 0 和 1 的strip，不是的用 -1 代替
                        //        DataTable loadStripInfo = STRIP_INFO.SelectScanedStripInfo(_availableAskStripsNoList);

                        //        //3.回写数据
                        //        if (!loadStripInfo.Equals(null) && loadStripInfo.Rows.Count > 0)
                        //        {
                        //            List<string> rspStripsValueList = new List<string>();
                        //            for (int i = 0; i < loadStripInfo.Rows.Count; i++)
                        //            {
                        //                string batchNoO = loadStripInfo.Rows[i][STRIP_INFO.fd_batchNoO].ToString();
                        //                string taskNo = loadStripInfo.Rows[i][STRIP_INFO.fd_taskNo].ToString();
                        //                string isSpy = loadStripInfo.Rows[i][STRIP_INFO.fd_isSpy].ToString();
                        //                string stripDurabilityClass = loadStripInfo.Rows[i][STRIP_INFO.fd_stripDurabilityClass].ToString();
                        //                string stripThk = Formats.ConvertUnit(loadStripInfo.Rows[i][STRIP_INFO.fd_stripThk].ToString(), VswUnit.STRIP_THK_L1,0);
                        //                string stripWidth = Formats.ConvertUnit(loadStripInfo.Rows[i][STRIP_INFO.fd_stripWidth].ToString(), VswUnit.STRIP_WIDTH_L1,0);
                        //                string burrDirection = loadStripInfo.Rows[i][STRIP_INFO.fd_burrDirection].ToString();
                        //                string stripWeight = loadStripInfo.Rows[i][STRIP_INFO.fd_stripWeight].ToString();

                        //                //如果数据库查出的是空，用 -1 补全这个字段
                        //                if (batchNoO.Equals(String.Empty))
                        //                {
                        //                    batchNoO = "-1";
                        //                }
                        //                if (taskNo.Equals(String.Empty))
                        //                {
                        //                    taskNo = "-1";
                        //                }
                        //                if (isSpy.Equals(String.Empty))
                        //                {
                        //                    isSpy = "-1";
                        //                }
                        //                if (stripDurabilityClass.Equals(String.Empty))
                        //                {
                        //                    stripDurabilityClass = "-1";
                        //                }
                        //                if (stripThk.Equals(String.Empty))
                        //                {
                        //                    stripThk = "-1";
                        //                }
                        //                if (stripWidth.Equals(String.Empty))
                        //                {
                        //                    stripWidth = "-1";
                        //                }
                        //                if (burrDirection.Equals(String.Empty))
                        //                {
                        //                    burrDirection = "-1";
                        //                }
                        //                if (stripWeight.Equals(String.Empty))
                        //                {
                        //                    stripWeight = "-1";
                        //                }
                        //                rspStripsValueList.Add(batchNoO);
                        //                rspStripsValueList.Add(taskNo);
                        //                rspStripsValueList.Add(isSpy);
                        //                rspStripsValueList.Add(stripDurabilityClass);
                        //                rspStripsValueList.Add(stripThk);
                        //                rspStripsValueList.Add(stripWidth);
                        //                rspStripsValueList.Add(burrDirection);
                        //                rspStripsValueList.Add(stripWeight);
                        //            }
                        //            opcServer.WriteValues(rspStripsValueList, opcNodes.StripLoadRspListAddress.GetNodeAddress().GetRange(0, rspStripsValueList.Count));

                        //            //向L3请求 status=0 的 strip BatchNo
                        //            L2INTF_BATCH.RequestBatchNo(loadStripInfo);

                        //            //扫描后改变strip状态由creted(0)->scaned(1)
                        //            STRIP_INFO.UpdateStripStatusAfterScaned(loadStripInfo);


                        //        }
                                
                        //    }

                        //}
                        //catch (Exception ex)
                        //{
                        //    LogHelper.WriteLog("SubscriptionHandler_StripLoadAddress", ex);
                        //}
                        //opcServer.WriteValue("true", opcNodes.StripLoadAddress.StripLoadRsp);


                    }
                    else
                    {
                        //Console.WriteLine("StripLoad requestData Reply");
                        //opcServer.WriteValue("false", opcNodes.StripLoadAddress.StripLoadRsp);

                        // 改成 int 型  0= 未请求  1= 请求成功  2= 请求失败
                        Console.WriteLine("StripLoad requestData Reply");
                        opcServer.WriteValue("0", opcNodes.StripLoadAddress.StripLoadRsp);
                    }
                }
            }

            //请求上卷
            if (monitoredItem.DisplayName == "SendDataAsk")
            {
                bool result = false;
                if (bool.TryParse(notification.Value.Value.ToString(), out result))
                {
                    //1.获取Strip上卷确认请求
                    Console.WriteLine("StripLoad confirm Load strip Ask");
                    if (result)
                    {
                        if (!STRIP_INFO.IsNullBatchNo(_availableAskStripsNoList))
                        {
                            try
                            {
                                //bool updateStatus = STRIP_INFO.UpdateAvailableStripStatus(_availableAskStripsNoList);
                                bool updateStatus = STRIP_INFO.UpdateStripStatusAfterLoad(_availableAskStripsNoList);
                                if (updateStatus)
                                {
                                    //上料后判断Task状态并改变
                                    TASK_INFO.UpdateTaskStatus(_availableAskStripsNoList[0]);
                                    opcServer.WriteValue("1", opcNodes.StripLoadAddress.SendDataRsp);
                                    Console.WriteLine("StripLoad Reply 1 at 229");
                                }
                                else
                                {
                                    opcServer.WriteValue("2", opcNodes.StripLoadAddress.SendDataRsp);
                                    Console.WriteLine("StripLoad Reply 2 at 234");
                                }
                            }
                            catch (Exception ex)
                            {
                                LogHelper.WriteLog("SendDataAsk", ex);
                                opcServer.WriteValue("2", opcNodes.StripLoadAddress.SendDataRsp);
                                Console.WriteLine("StripLoad Reply 2 at 241");
                            }
                        }
                        else
                        {
                            opcServer.WriteValue("2", opcNodes.StripLoadAddress.SendDataRsp);
                            Console.WriteLine("StripLoad Reply 2 at 247");
                        }
                    }
                    else
                    {
                        Console.WriteLine("StripLoad confirm Load strip response");
                        opcServer.WriteValue("0", opcNodes.StripLoadAddress.SendDataRsp);
                        //Console.WriteLine("回写=0");
                    }
                }
            }
        }

        /// <summary>
        /// 获取扫码STRIP_NO 列表
        /// </summary>
        /// <param name="monitoredItem"></param>
        /// <param name="e"></param>
		private void SubscriptionHandler_StripLoadAskListAddress(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            //System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            //stopwatch.Start();
            MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
            if (notification == null || notification.Value.Value == null)
                return;
            switch (monitoredItem.DisplayName)
            {
                case "StripNode_1":
                    {
                        //if (!notification.Value.Value.Equals(null) && notification.Value.Value != null)
                        //{
                        //    _askStripsNoList[1] = notification.Value.Value.ToString();
                        //}
                        //else
                        //    _askStripsNoList[1] = "0";

                        try
                        {
                            _askStripsNoList[0] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[0] = "0";
                        }
                        break;
                    }
                case "StripNode_2":
                    {
                        try
                        {
                            _askStripsNoList[1] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[1] = "0";
                        }
                        break;
                    }
                case "StripNode_3":
                    {
                        try
                        {
                            _askStripsNoList[2] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[2] = "0";
                        }
                        break;
                    }
                case "StripNode_4":
                    {
                        try
                        {
                            _askStripsNoList[3] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[3] = "0";
                        }
                        break;
                    }
                case "StripNode_5":
                    {
                        try
                        {
                            _askStripsNoList[4] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[4] = "0";
                        }
                        break;
                    }
                case "StripNode_6":
                    {
                        try
                        {
                            _askStripsNoList[5] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[5] = "0";
                        }
                        break;
                    }
                case "StripNode_7":
                    {
                        try
                        {
                            _askStripsNoList[6] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[6] = "0";
                        }
                        break;
                    }
                case "StripNode_8":
                    {
                        try
                        {
                            _askStripsNoList[7] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[7] = "0";
                        }
                        break;
                    }
                case "StripNode_9":
                    {
                        try
                        {
                            _askStripsNoList[8] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[8] = "0";
                        }
                        break;
                    }
                case "StripNode_10":
                    {
                        try
                        {
                            _askStripsNoList[9] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[9] = "0";
                        }
                        break;
                    }
                case "StripNode_11":
                    {
                        try
                        {
                            _askStripsNoList[10] = notification.Value.Value.ToString();
                        }
                        catch
                        {
                            _askStripsNoList[10] = "0";
                        }
                        break;
                    }
            }
        }

        /// <summary>
        /// STRIP INFO 回写地址
        /// </summary>
        /// <param name="monitoredItem"></param>
        /// <param name="e"></param>
		private void SubscriptionHandler_StripLoadRspListAddress(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
            if (notification == null || notification.Value.Value == null)
                return;
            //list rspvalue=value
        }


        /// <summary>
        /// strip 进入开卷机
        /// </summary>
        /// <param name="monitoredItem"></param>
        /// <param name="e"></param>
        private void SubscriptionHandler_StripLoadInUncoiler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
            if (notification == null || notification.Value.Value == null)
                return;

            if (monitoredItem.DisplayName== "Strip_No")
            {
                string stripNo= notification.Value.Value.ToString();
                if (string.IsNullOrEmpty(stripNo))
                {
                    return;
                }
                Task.Run(() => ChangStripStatusToUncoil(stripNo));
            }   
        }
        private async Task ChangStripStatusToUncoil(string stipeNo)
        {
            try
            {
                await Task.Delay(100);
                STRIP_INFO.UpdateStripStatusAfterUncoil(stipeNo);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("ChangStripStatusToUncoil", ex);
            }
        }


        private async Task RequestStripInfo()
        {
            int savedRequestId = requestId;
            GetAvailableAskStripsNoList();
            int result = 2;
            
            try
            {           
                //2. 获取数据库表中可以上料的Strip
                if (!_availableAskStripsNoList.Equals(null) && _availableAskStripsNoList.Count > 0)
                {
                    int scaned = 0;
                    //查出 _availableAskStripsNoList 里状态是 0 和 1 的strip 的信息，不是的用 -1 代替, 并返回有bath id 信息的钢卷的数量
                    DataTable loadStripInfo = STRIP_INFO.CheckScanedStripInfo(_availableAskStripsNoList,out scaned);
                    
                    //如果有的卷没有数据
                    if(scaned < _availableAskStripsNoList.Count)
                    {
                        //向 L3 请求 batch id 
                        L2INTF_BATCH.RequestBatchNoV2(loadStripInfo);

                        //等 12 秒
                        await Task.Delay(20000);

                        // 再查询一遍，是否所有请求的的 strip 都有 batch id
                        int failCount = STRIP_INFO.CheckRestScanedStripInfo(loadStripInfo);
                        if(failCount==0)
                        {
                            result = 1;
                        }
                        else
                        {
                            Console.WriteLine("Inquire Strip has no batch ID at 497");
                        }
                    }
                    else
                    {
                        result = 1;
                    }
                    
                    //3.回写数据
                    if (stripLoadAskResult && (savedRequestId==requestId) && (!loadStripInfo.Equals(null)) && loadStripInfo.Rows.Count > 0)
                    {
                        List<string> rspStripsValueList = new List<string>();
                        for (int i = 0; i < loadStripInfo.Rows.Count; i++)
                        {
                            string batchNoO = loadStripInfo.Rows[i][STRIP_INFO.fd_batchNoO].ToString();
                            string taskNo = loadStripInfo.Rows[i][STRIP_INFO.fd_taskNo].ToString();
                            string isSpy = loadStripInfo.Rows[i][STRIP_INFO.fd_isSpy].ToString();
                            string stripDurabilityClass = loadStripInfo.Rows[i][STRIP_INFO.fd_stripDurabilityClass].ToString();
                            string stripThk = Formats.ConvertUnit(loadStripInfo.Rows[i][STRIP_INFO.fd_stripThk].ToString(), VswUnit.STRIP_THK_L1, 0);

                            //Console.WriteLine("input:  " + loadStripInfo.Rows[i][STRIP_INFO.fd_stripThk].ToString());

                            string stripWidth = Formats.ConvertUnit(loadStripInfo.Rows[i][STRIP_INFO.fd_stripWidth].ToString(), VswUnit.STRIP_WIDTH_L1, 0);
                            string burrDirection = loadStripInfo.Rows[i][STRIP_INFO.fd_burrDirection].ToString();
                            string stripWeight = loadStripInfo.Rows[i][STRIP_INFO.fd_stripWeight].ToString();
                            //如果数据库查出的是空，用 -1 补全这个字段
                            if (batchNoO.Equals(String.Empty))
                            {
                                batchNoO = "-1";
                            }
                            if (taskNo.Equals(String.Empty))
                            {
                                taskNo = "-1";
                            }
                            if (isSpy.Equals(String.Empty))
                            {
                                isSpy = "-1";
                            }
                            if (stripDurabilityClass.Equals(String.Empty))
                            {
                                stripDurabilityClass = "-1";
                            }
                            if (stripThk.Equals(String.Empty))
                            {
                                stripThk = "-1";
                            }
                            if (stripWidth.Equals(String.Empty))
                            {
                                stripWidth = "-1";
                            }
                            if (burrDirection.Equals(String.Empty))
                            {
                                burrDirection = "-1";
                            }
                            if (stripWeight.Equals(String.Empty))
                            {
                                stripWeight = "-1";
                            }
                            rspStripsValueList.Add(batchNoO);
                            rspStripsValueList.Add(taskNo);
                            rspStripsValueList.Add(isSpy);
                            rspStripsValueList.Add(stripDurabilityClass);
                            rspStripsValueList.Add(stripThk);
                            rspStripsValueList.Add(stripWidth);
                            rspStripsValueList.Add(burrDirection);
                            rspStripsValueList.Add(stripWeight);
                        }



                        ////var tmtm = opcNodes.StripLoadRspListAddress.GetNodeAddress().GetRange(0, rspStripsValueList.Count);
                        ////for (int i = 0; i < rspStripsValueList.Count; i++)
                        ////{
                        ////    Console.WriteLine(tmtm[i] + " : " + rspStripsValueList[i]);
                        ////}


                        opcServer.WriteValues(rspStripsValueList, opcNodes.StripLoadRspListAddress.GetNodeAddress().GetRange(0, rspStripsValueList.Count));
                       
                    }

                }

            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("SubscriptionHandler_StripLoadAddress", ex);
                result = 2;
            }
            if(stripLoadAskResult && (savedRequestId == requestId))
            {
                opcServer.WriteValue(result.ToString(), opcNodes.StripLoadAddress.StripLoadRsp);
                Console.WriteLine("StripInquire Reply {0} at 586",result);
            }
            else
            {
                Console.WriteLine("Inquire strip time out at 593");
            }
            
        }



        /// <summary>
        /// 获取非 0  的卷号,并将它们加入到 availableAskStripsNoList 集合
        /// </summary>
        private void GetAvailableAskStripsNoList()
        {
            _availableAskStripsNoList.Clear();
            for (int i = 0; i < _askStripsNoList.Length; i++)
            {
                //**whj1109**
                //请求序列
                //Console.WriteLine("打印请求集合：" + askStripsNoList[i]);
                if (!_askStripsNoList[i].Equals(null) && !_askStripsNoList[i].Equals("0")&& !string.IsNullOrWhiteSpace(_askStripsNoList[i])&& !string.IsNullOrEmpty(_askStripsNoList[i]))
                {
                    if(Int64.TryParse(_askStripsNoList[i],out long result))
                    {
                        if (!_availableAskStripsNoList.Contains(_askStripsNoList[i]))
                        {
                            _availableAskStripsNoList.Add(_askStripsNoList[i]);
                        }
                    }
                    
                }
                else
                    return;
            }
        }

    }
}
